#!/usr/bin/env python

# -*- coding: UTF-8 -*-

# to play subtitles properly add -subpos 90 -spualign 2 -spuaa 4 to mplayer
#custom colors: ON, tridx: 0001, colors: ffffff,000000,000000,000000
#custom colors: ON, tridx: 0100, colors: 000000,000000,ffffff,000000
#custom colors: ON, tridx: 0000, colors: 000000,ffffff,000000,ffffff


from gui import Ui_dvd
from file import file
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys,re,urllib

def uniq(l):
	res = []
	for i in l:
		if i not in res:
			res += [i]
	return res
	

class MainWindow(QWidget, Ui_dvd):
	def __init__(self, parent = None):
		QWidget.__init__(self, parent)
		self.setupUi(self)
		
		# no implementado todavia
		self.listaCapitulos.hide()

		# dvd
		self.dvdDev = "/dev/dvd"
		self.boxOrigen.setText(self.dvdDev)
		self.dvd = file(self.dvdDev)
		self.dvdDest = "/tmp/"
		self.dvdDelay = 0
		self.dvdTitle = 1
		self.dvdAspect = ''
		self.btnPlay.setEnabled(0)
		self.btnRip.setEnabled(0)


		#self.dvdReload()
		self.connect(self.btnOrigenIso,SIGNAL("clicked()"),self.dvdSelectIso)
		self.connect(self.btnOrigenDir,SIGNAL("clicked()"),self.dvdSelectDir)
		self.connect(self.btnDestino,SIGNAL("clicked()"),self.dvdChangeDest)
		self.connect(self.btnRip,SIGNAL("clicked()"),self.ripDvd)
		self.connect(self.btnReload,SIGNAL("clicked()"),self.dvdReload)
		self.connect(self.btnPlay,SIGNAL("clicked()"),self.dvdPlay)
		self.connect(self.btnTitle,SIGNAL("currentIndexChanged(int)"),self.updateTitleData)
		self.connect(self.btnContenedor,SIGNAL("currentIndexChanged(int)"),self.updateContainers)
		self.connect(self.wtdCapitulos,SIGNAL("clicked()"),self.changeChap)
		self.audioList.setColumnWidth(0,50)
		self.audioList.setColumnWidth(1,50)
		self.audioList.setColumnWidth(2,60)
		self.audioList.setColumnWidth(3,50)
		#self.audioList.setColumnWidth(4,60)
		self.subList.setColumnWidth(0,50)
                                              

		# editor mkvs
		self.mkvSource = "/tmp/"
		self.mkvTable.setColumnWidth(0,260)
		self.mkvTable.setColumnWidth(1,30)
		self.mkvTable.setColumnWidth(2,60)
		self.mkvTable.setColumnWidth(3,50)
		self.mkvTable.setColumnWidth(4,70)
		self.mkvTable.setColumnWidth(5,80)
		self.mkvTable.setColumnWidth(6,20)
		self.mkvTable.setColumnWidth(7,50)
		self.mkvTable.setColumnWidth(8,70)
		self.mkvTable.setColumnWidth(9,50)
		self.mkvTable.setColumnWidth(10,50)
		self.connect(self.MkvBtnOrigen,SIGNAL("clicked()"),self.addMkvFiles)
		self.connect(self.MkvBtnMake,SIGNAL("clicked()"),self.joinMkv)
		self.connect(self.mkvClean,SIGNAL("clicked()"),self.cleanMkv)
		self.connect(self.MkvBtnDest,SIGNAL("clicked()"),self.selectDestMkv)
		
		# conversor
		self.connect(self.convBtnOrg	,SIGNAL("clicked()"),self.selectOrgConv)		
		self.connect(self.convBtnDest	,SIGNAL("clicked()"),self.selectDestConv)		
		self.connect(self.convBtnRip	,SIGNAL("clicked()"),self.ripConv)		

	def changeChap(self):
		if self.wtdCapitulos.checkState():
			self.listaCapitulos.hide()
		else:
			self.listaCapitulos.show()

	def selectOrgConv(self):
		# conversor
		dest = QFileDialog.getOpenFileName(self, "Selecciona un fichero",  "/tmp", QString('movie file (*.avi *.mpg *.mpeg *.mkv *.mp4);;All files (*.*)'))
		if dest <> "":
			self.convBoxOrg.setText(dest)

	def selectDestConv(self):
		# conversor
		dest = QFileDialog.getSaveFileName(self, "Selecciona o escribe el nombre del fichero a salvar",  "/tmp", QString('movie file (*.avi);;All files (*.*)'))
		if dest <> "":
			self.convBoxDest.setText(dest)

	def ripConv(self):
		# conversor
		format = self.convBtnFormat.currentIndex()
		cropCmd = ""
		if self.convOptCrop.checkState():
			cropCmd = self.cropping("\"" + str(self.convBoxOrg.text()) + "\"")
		if format == 0: # iphone
			cmd = "mencoder -noautosub \"" + str(self.convBoxOrg.text()) + "\"  -oac copy -ovc x264 -vf pullup,softskip" + cropCmd + ",scale=320:240,harddup -ofps 25.000 -x264encopts pass=1:bitrate=365:keyint=250:keyint_min=25:nocabac:level_idc=30:nocabac:frameref=3:turbo=1:partitions=all:mixed_refs=1:fast_pskip=0:threads=auto -o /dev/null -sws 1\n"
			cmd += "mencoder -noautosub \"" + str(self.convBoxOrg.text()) + "\" -oac copy -ovc x264 -vf pullup,softskip" + cropCmd + ",scale=320:240,harddup -ofps 25.000 -x264encopts pass=2:bitrate=365:keyint=250:keyint_min=25:nocabac:level_idc=30:nocabac:frameref=3:turbo=1:partitions=all:mixed_refs=1:fast_pskip=0:threads=auto -o \"" + str(self.convBoxDest.text()) + ".avi\" -sws 1\n"
			cmd += "mplayer -noautosub \"" + str(self.convBoxDest.text()) + ".avi\" -vc null -vo null -ao pcm:fast:file=\"" + str(self.convBoxDest.text()) + ".wav\" -noconsolecontrols -nolirc -nojoystick -nomouseinput\n"
			cmd += "faac -o \"" + str(self.convBoxDest.text()) + ".m4a\" \"" + str(self.convBoxDest.text()) + ".wav\"\n"
			if self.convOptGain.checkState():
				cmd += "aacgain -r -k \"" + str(self.convBoxDest.text()) + ".m4a\"\n"
			cmd += "MP4Box -aviraw video \"" + str(self.convBoxDest.text()) + ".avi\"\n"
			cmd += "MP4Box -new -add \"" + str(self.convBoxDest.text()) + ".m4a\"  -add \"" + str(self.convBoxDest.text()) + "_video.h264\":fps=25.000 -tmp /tmp/ \"" + str(self.convBoxDest.text()) + ".mp4\"\n"
		elif format == 1: # 3gp 176x144
			cmd = "ffmpeg -i \"" + str(self.convBoxOrg.text()) + "\" -s qcif  -f 3gp -vcodec mpeg4 -acodec libfaac -ar 8000 -ac 1 -ab 12.2k -y \"" + str(self.convBoxDest.text()) + "\""
		elif format == 2: # 3gp 320x240 
			cmd = "ffmpeg -i \"" + str(self.convBoxOrg.text()) + "\" -s qvga  -f 3gp -vcodec mpeg4 -acodec libfaac -ar 8000 -ac 1 -ab 12.2k -y \"" + str(self.convBoxDest.text()) + "\""

		self.convLog.insertPlainText (cmd + "\n")
		
	
	def selectDestMkv(self):
		# editor mkvs
		dest = QFileDialog.getSaveFileName(self, "Selecciona o escribe el nombre del fichero a salvar",  "/tmp",)
		if dest <> "":
			self.MkvBoxDest.setText(dest)
		
	def cleanMkv(self):
		# editor mkvs
		for i in range(self.mkvTable.rowCount()):
			self.mkvTable.removeRow(0)
	
	def joinMkv(self):
		# editor mkvs
		cmd = ""
		lang = ""
		sel = []
		for i in  self.mkvTable.selectedItems():
			sel += [i.row()]
		for i in uniq(sel): 
			id = self.mkvTable.item(i,1).text()
			delay = str(self.mkvTable.cellWidget(i,4).value())
			name = self.mkvTable.item(i,0).text()
			tipo = self.mkvTable.item(i,2).text()
			if tipo == "audio":
				filtro = " -S -D -B --no-chapters --no-attachments --no-tags "
				track = " -a "+id + " "
			if tipo == "subtitulo":
				filtro = " -A -D -B --no-chapters --no-attachments --no-tags "
				track = " -s "+id + " "
				
			if tipo == "video":
				filtro = " -A -S -B --no-chapters --no-attachments --no-tags "
				track = " -d "+id + " "
				lang = ""
				cmd +=  track + filtro + " --sync " + id + ":" + delay + " \"" + name + "\" "
			else:
				lang = " --language " + id + ":" + self.mkvTable.cellWidget(i,3).currentText() 
				cmd +=  track + filtro + " --sync " + id + ":" + delay + "ms" + lang + " \"" + name + "\" "
				
			lang = ""
		self.mkvLog.insertPlainText ("\nmkvmerge -o \"" + self.MkvBoxDest.text() + "\" " + cmd+ "\n")
		print "mkvmerge -o \"" + self.MkvBoxDest.text() + "\" " + cmd + "\n"

	def addMkvFiles(self):
		# editor mkvs
		files = QFileDialog.getOpenFileNames(self, "Selecciona un fichero",  self.mkvSource,)
		if not files.isEmpty():
			self.mkvSource = "/".join(str(files[0]).split("/")[:-1])
			for i in range(files.count()):
				self.addMkvFile(files[i])

	def addMkvFile(self,fichero):
		# editor mkvs
		listaIdiomas = ["spa","eng","fre","ger","ita","por","und"]
		id = 0
		if (fichero <> ""):
			f = file(str(fichero))
			f.load()
			name = fichero
			vid = f.vid 
			aid = f.aid 
			sid = f.sid 
			fila = self.mkvTable.rowCount()
			for i in vid.keys():
				self.mkvTable.insertRow(fila)
				self.mkvTable.setItem(fila, 0, QTableWidgetItem(name))
				self.mkvTable.setItem(fila, 1, QTableWidgetItem(str(vid[i]['mkvId'])))
				self.mkvTable.setItem(fila, 2, QTableWidgetItem(str("video")))
				spin = QSpinBox()
				spin.setRange(-99999999,99999999)
				self.mkvTable.setCellWidget(fila, 4, spin)
				self.mkvTable.setItem(fila, 5, QTableWidgetItem(str(vid[i]['codec'])))
				self.mkvTable.setItem(fila, 7, QTableWidgetItem(str(vid[i]['format'])))
				self.mkvTable.setItem(fila, 8, QTableWidgetItem(str(vid[i]['ancho']+"x"+vid[i]['alto'])))
				self.mkvTable.setItem(fila, 9, QTableWidgetItem(str(vid[i]['aspect'])))
				self.mkvTable.setItem(fila, 10, QTableWidgetItem(str(vid[i]['fps'])))
				fila += 1
			for i in aid.keys():
				self.mkvTable.insertRow(fila)
				self.mkvTable.setItem(fila, 0, QTableWidgetItem(name))
				self.mkvTable.setItem(fila, 1, QTableWidgetItem(str(aid[i]['mkvId'])))
				self.mkvTable.setItem(fila, 2, QTableWidgetItem(str("audio")))
				if "idioma" in aid[i].keys() :listaIdiomas = [aid[i]['idioma']] + listaIdiomas
				else : listaIdiomas = ["und"] + listaIdiomas
				langs = QComboBox()
				langs.addItems(uniq(listaIdiomas))
				self.mkvTable.setCellWidget(fila, 3, langs)
				spin = QSpinBox()
				spin.setRange(-99999999,99999999)
				self.mkvTable.setCellWidget(fila, 4, spin)
				self.mkvTable.setItem(fila, 5, QTableWidgetItem(str(aid[i]['codec'])))
				self.mkvTable.setItem(fila, 6, QTableWidgetItem(str(aid[i]['ch'])))
				fila += 1
			for i in sid.keys():
				self.mkvTable.insertRow(fila)
				self.mkvTable.setItem(fila, 0, QTableWidgetItem(name))
				self.mkvTable.setItem(fila, 1, QTableWidgetItem(str(sid[i]['mkvId'])))
				self.mkvTable.setItem(fila, 2, QTableWidgetItem(QString("subtitulo")))
				if "idioma" in sid[i].keys() :listaIdiomas = [expLang(sid[i]['idioma'])] + listaIdiomas
				else : listaIdiomas = ["und"] + listaIdiomas
				langs = QComboBox()
				langs.addItems(uniq(listaIdiomas))
				self.mkvTable.setCellWidget(fila, 3, langs)
				spin = QSpinBox()
				spin.setRange(-99999999,99999999)
				self.mkvTable.setCellWidget(fila, 4, spin)
				self.mkvTable.setItem(fila, 5, QTableWidgetItem(str(sid[i]['codec'])))
				fila += 1
				
	def cropping (self, file):
		# conversor y dvd
		import re, sys
		crops = []
		cmd = "mplayer -idx " + file + " -nosound -vo null -frames 0 -identify"
		print "### ", cmd
		long = int(float(re.search("ID_LENGTH=(.*?)\n",commands.getoutput(cmd)).groups()[0]))
		for ss in [int(long/6),(long/3),int(long/1.7),int(long/1.3)]:
			cmd = str("mplayer " + file + " -idx -nosound -vo null -vf cropdetect -ss " + str(ss) +" -frames 15 -speed 100")
			print "### ", cmd
			cropData = commands.getoutput(cmd)
			for i in cropData.split("\n"):
				try:
					crops.append(re.search("(\d+:\d+:\d+:\d+)\)", i).groups()[0])
				except AttributeError:
					pass
		maxCount = 0
		cropCmd = ""
		for i in crops:
			if crops.count(i) > maxCount:
				maxCount = crops.count(i)
				cropCmd = i
		if cropCmd == "":
			print "\n\n NO SE HA ENCONTRADO CROPPING"
			sys.exit(-1)
		print ",crop=" + cropCmd
		return ",crop=" + cropCmd
				
			

	def dvdChangeDest(self):
		dest = QFileDialog.getExistingDirectory(self, "Escoge un destino",  str(self.boxDestino.text()),)
		if dest <> "":
			self.boxDestino.setText(dest)

	def dvdSelectIso(self):
		dvd = QFileDialog.getOpenFileName(self, "Selecciona  la imagen de dvd",  "/tmp", QString('imagen de dvd (*.iso);;All files (*.*)'))
		if (dvd <> ""):
			self.wtdRip.setChecked(0)
			self.dvdDev = str(dvd) 
			self.boxOrigen.setText(self.dvdDev)
			self.dvd.device = self.dvdDev
			self.dvdReload()

	def dvdSelectDir(self):
		dvd = QFileDialog.getExistingDirectory(self, "Selecciona el directorio de dvd",  "/tmp",)
		if (dvd <> ""):
			self.wtdRip.setChecked(0)
			self.dvdDev = str(dvd) 
			self.boxOrigen.setText(self.dvdDev)
			self.dvd.device = self.dvdDev
			self.dvdReload()

	def dvdReload(self):
		self.dvd.clear()
		self.dvdDev = str(self.boxOrigen.text())
		self.dvd.device = self.dvdDev
		self.dvd.load(self.dvdTitle)
		for i in range(self.audioList.rowCount()):
			self.subList.removeRow(0)
		for i in range(self.subList.rowCount()):
			self.subList.removeRow(0)
		self.btnTitle.clear()
		print self.dvd.data
		for i in self.dvd.titles.keys():
			try:
				self.btnTitle.addItem("Titulo # " + str(i) + " long: " + seg2time(self.dvd.titles[i]['duracion']) + " hr")
			except :
				self.btnTitle.addItem("Titulo # " + str(i))
		if len(self.dvd.titles.keys()) <> 0:
			self.btnPlay.setEnabled(1)
			self.btnRip.setEnabled(1)
		else:
			self.btnPlay.setEnabled(0)
			self.btnRip.setEnabled(0)

	def dvdPlay(self):
		import commands	
		if len(self.audioList.selectedItems()) == 0:
			aid = ""
		else :
			aid = "-aid " + self.dvd.titles[self.dvdTitle]['aid'][int(self.audioList.selectedItems()[0].row())]['aid']
		if len(self.subList.selectedItems()) == 0:
			sid = ""
		else :
			sid = "-sid " + str(self.subList.selectedItems()[0].row())
		if not self.wtdCapitulos.checkState():
			if self.listaCapitulos.selectedItems() <> []:
				self.dvdChapters = str(self.listaCapitulos.row(self.listaCapitulos.selectedItems()[0])+1) + "-" + str(self.listaCapitulos.row(self.listaCapitulos.selectedItems()[-1])+1)
		else:
			self.dvdChapters = "0"
		cmd = "mplayer dvd://" + str(self.dvdTitle) + " -dvd-device \"" + self.dvdDev + "\" " + str(aid) + " " + str(sid) + " -chapter " + self.dvdChapters
		print "### ",cmd
		cmdOut = commands.getoutput(cmd)

	def updateContainers(self,i):
		self.updateTitleData(self.dvdTitle - 1)

	def updateTitleData(self, titulo):
		self.listaCapitulos.clear()
		aidSel = []
		for i in  self.audioList.selectedItems():
			aidSel += [(i.row(),str(self.audioList.cellWidget(int(self.dvd.titles[self.dvdTitle]['aid'][i.row()]['id']),5).currentText()))]
		sidSel = []
		for i in  self.subList.selectedItems():
			sidSel += [i.row()]
		if titulo >= 0:
			for i in range(self.audioList.rowCount()):
				self.audioList.removeRow(0)
			for i in range(self.subList.rowCount()):
				self.subList.removeRow(0)
			self.dvdTitle = int(titulo) + 1
			if not self.dvd.titles[self.dvdTitle]['scanned']:
				self.dvd.load(self.dvdTitle)
			try:
				self.listaCapitulos.addItems(self.dvd.titles[self.dvdTitle]['vid']['chapters'])
				self.dvdChapters = "1-"+str(len(self.dvd.titles[self.dvdTitle]['vid']['chapters']))
			except:
				self.listaCapitulos.addItem('00:00:00')
			aid = self.dvd.titles[self.dvdTitle]['aid']
			listaIdiomas = ["spa","eng","fre","ger","ita","por","und"]
			fila = 0
			for i in aid.keys():
				listaCodec = ['ac3', 'mp3', 'ogg stereo', 'aac stereo']
				if str(self.btnContenedor.currentText()) == 'mp4':
					listaCodec = ['mp3', 'ogg stereo', 'aac stereo']
				self.audioList.insertRow(fila)
				self.audioList.setItem(fila, 0, QTableWidgetItem(str(aid[i]['id'])))
				self.audioList.setItem(fila, 1, QTableWidgetItem(str(aid[i]['aid'])))
				self.audioList.setItem(fila, 2, QTableWidgetItem(str(aid[i]['ch'])))
				self.audioList.setItem(fila, 3, QTableWidgetItem(str(expLang(aid[i]['idioma']))))
				self.audioList.setItem(fila, 4, QTableWidgetItem(str(aid[i]['formato'])))
				codec= QComboBox()
				if aid[i]['ch'] == "5.1": 
					listaCodec = ['ac3', 'mp3', 'ogg stereo','aac stereo','ogg 5.1','aac 5.1']
					if str(self.btnContenedor.currentText()) == 'mp4':
						listaCodec = ['mp3', 'ogg stereo','aac stereo','ogg 5.1','aac 5.1']
						
				codec.addItems(listaCodec)
				self.audioList.setCellWidget(fila, 5, codec)
				fila += 1
			sid = self.dvd.titles[self.dvdTitle]['sid']
			fila = 0
			for i in sid.keys():
				self.subList.insertRow(fila)
				self.subList.setItem(fila, 0, QTableWidgetItem(str(sid[i]['id'])))
				self.subList.setItem(fila, 1, QTableWidgetItem(str(expLang(sid[i]['idioma']))))
				fila += 1
			for i in uniq(aidSel): 
				self.audioList.selectRow(i[0])
				for j in range(self.audioList.cellWidget(i[0],5).count()):
					if self.audioList.cellWidget(i[0],5).itemText(j) == i[1]:
						self.audioList.cellWidget(i[0],5).setCurrentIndex(j)
			for i in uniq(sidSel): 
				self.subList.selectRow(i)

	def ripDvd(self):
		import commands
		self.dvdDest = str(self.boxDestino.text())
		if self.dvdDest[-1] <> "/":
			self.dvdDest += "/"
		vcodec = self.btnVideo.currentText()
		self.dvdMkv = []
		ripeado = ""
		encode = ""
		if not self.wtdCapitulos.checkState():
			if self.listaCapitulos.selectedItems() <> []:
				self.dvdChapters = str(self.listaCapitulos.row(self.listaCapitulos.selectedItems()[0])+1) + "-" + str(self.listaCapitulos.row(self.listaCapitulos.selectedItems()[-1])+1)
			else:
				self.dvdChapters = "1-"+str(len(self.dvd.titles[self.dvdTitle]['vid']['chapters']))
		else:
			self.dvdChapters = "1-"+str(len(self.dvd.titles[self.dvdTitle]['vid']['chapters']))
			
		if self.wtdRip.checkState():
			volcado = self.volcado()
			ripeado += volcado
		if self.wtdSub.checkState():
			sid = []
			for i in self.subList.selectedItems():
				sid += [int(self.subList.item(i.row(),0).text())]
			for i in uniq(sid):
				sub = self.subtitulos(self.dvd.titles[self.dvdTitle]['sid'][i])
				encode += sub
		if self.wtdAudio.checkState():
			aid = []
			for i in self.audioList.selectedItems():
				aid += [i.row()]
			for i in uniq(aid):
				audio = self.audio(self.dvd.titles[self.dvdTitle]['aid'][i])
				encode += audio
		if self.wtdVideo.checkState():
			video = self.video()
			encode += video
		if self.wtdChap.checkState():
			if self.btnContenedor.currentText() == 'mkv':
				makeMkv = self.makeMkv(1)
			if self.btnContenedor.currentText() == 'mp4':
				makeMkv = self.makeMp4(1)
			self.chapters()
		else: 
			if self.btnContenedor.currentText() == 'mkv':
				makeMkv = self.makeMkv(0)
			if self.btnContenedor.currentText() == 'mp4':
				makeMkv = self.makeMp4(0)
		if self.dvdMkv <> []:
				encode += makeMkv
			
		if encode:
			f = open (self.dvdDest+"/encode.sh",'a')
			f.write(encode)
			f.close()
		if ripeado :
			datosRipAnterior = [""]
			try:
				f = open (self.dvdDest+"/rip.sh",'r')
				datosRipAnterior = f.readlines() 
				f.close()
			except:
				pass
			f = open (self.dvdDest+"/rip.sh",'w')
			f.truncate()
			if self.dvdDev == "/dev/dvd":
				f.writelines(datosRipAnterior[:-1])
			else:
				f.writelines(datosRipAnterior)
			f.write(ripeado)
			f.close()
		print "\n# Ahora Lo que hay que hacer"
		print ripeado
		print encode

	def volcado (self):
		text = "mplayer -noconsolecontrols -noautosub -nojoystick -nomouseinput -nolirc -chapter " + self.dvdChapters + " dvd://"+str(self.dvdTitle)+" -dvd-device \"" + self.dvdDev + "\" -dumpstream -dumpfile \"" + str(self.dvdDest)+"dvd-t"+str(self.dvdTitle)+".vob\"\n"
		if self.dvdDev == "/dev/dvd":
			text += "eject " + self.dvdDev + "\n"
		return text

	def makeMp4 (self,chap):
		text = "MP4Box -new -brand mp42 -tmp \"" + str(self.dvdDest)+ "\" "
		for i in self.dvdMkv:
			if 'video' in i[0]:
				if '264' in i[0]: 
					text += ' -add '+str(i[0])+':fmt=h264:fps=25.000#video'
				if 'xvid' in i[0]: 
					text += ' -add '+str(i[0])+':fmt=mpeg4-video:fps=25.000#video'
			elif 'audio' in i[0]:
				if "aac" in i[0]:
					text += ' -add '+str(i[0])+':fmt=aac:lang='+i[1]+':delay=' + str(self.dvdDelay) + '#audio'
				elif "mp3" in i[0]:
					text += ' -add '+str(i[0])+':fmt=mp3:lang='+i[1]+':delay=' + str(self.dvdDelay) + '#audio'
				elif "ogg" in i[0]:
					text += ' -add '+str(i[0])+':fmt=ogg:lang='+i[1]+':delay=' + str(self.dvdDelay) + '#audio'
			elif 'sub' in i[0]:
				text += " -add "  + str(i[0]) + ':fmt=vobsub:lang='+i[1]+':delay=' + str(self.dvdDelay)
		if chap:
			text += " -chap \"" + str(self.dvdDest)+"chapter-T"+str(self.dvdTitle)+".txt\""
		text += " \"" + str(self.dvdDest)+ "final-dvd-T" + str(self.dvdTitle) + ".mp4\"\n"
		return text

	def makeMkv (self,chap):
		text = "mkvmerge -o \"" + str(self.dvdDest)+ "final-dvd-T" + str(self.dvdTitle) + ".mkv\""
		for i in self.dvdMkv:
			print [i]
			if 'video' in i[0]:
				text += ' -A -S -B --no-chapters --no-attachments --no-tags --aspect-ratio 0:' + str(self.dvdAspect) + " " + str(i[0])
			elif 'audio' in i[0]:
				text += ' -S -D -B --no-chapters --no-attachments --no-tags --language 0:' + i[1]+ ' -y 0:' + str(self.dvdDelay) + 'ms ' + str(i[0])
			elif 'sub' in i[0]:
				if "idx" in i[0]:
					text += " -A -D -B --no-chapters --no-attachments --no-tags -y 0:" + str(self.dvdDelay) + 'ms '  + str(i[0]) 
				else:
					text += " -A -D -B --no-chapters --no-attachments --no-tags -y 1:" + str(self.dvdDelay) + 'ms '  + str(i[0]) 
		if chap:
			text += " --chapter-language spa  --chapters \"" + str(self.dvdDest)+"chapter-T"+str(self.dvdTitle)+".txt\"\n"
		else:
			text += "\n"
		return text

	def audio (self,audio):
		import re
		text = ""
		print audio
		aCodec = self.audioList.cellWidget(int(audio['id']),5).currentText() 
		id 	= str(audio['id']) 
		aid 	= str(audio['aid']) 
		lang 	= str(audio['idioma'])
		codec 	= str(audio['formato'])
		fid 	= "audio-t"+str(self.dvdTitle)+"-"+str(audio['id'])+"-"+str(audio['idioma'])
		lang3 	= expLang(str(audio['idioma']))
		noes = "-noconsolecontrols -noautosub -nojoystick -nomouseinput -nolirc -nocache -noslices -noframedrop"
		if self.dvdDev == '/dev/dvd' or self.wtdRip.checkState():
			org = " -chapter " + self.dvdChapters + " \"" + str(self.dvdDest)+"dvd-t"+str(self.dvdTitle)+".vob\""
		else :
			org = " -chapter " + self.dvdChapters + " dvd://"+str(self.dvdTitle)+" -dvd-device \"" + str(self.dvdDev) + "\""
			
		if aCodec == "ac3":
			text += "mencoder -nocache -mc 0 -aid " + str(aid) + " -o \"" + str(self.dvdDest) + fid + ".ac3\" -ovc frameno -of rawaudio -oac copy " + org + "\n" 
			self.dvdMkv += [["\"" + str(self.dvdDest) + fid + ".ac3\"",lang3]]
			print self.dvdMkv
			
		elif aCodec == "ogg stereo":
			text += "mkfifo \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			text += "oggenc -r -R 44100 -q 3 -C 2 -o \"" + str(self.dvdDest) + fid + ".ogg\" \"" + str(self.dvdDest)+ "fifo-" + fid + "\"&"
			text += " mplayer " + noes + " -noframedrop -mc 0 -vc null -vo null -ao pcm:nowaveheader:file=\"" + str(self.dvdDest)+ "fifo-" + fid + "\" -srate 44100 -af volnorm=1 -aid " + str(aid) + " " + org + "\n"
			text += "rm \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			self.dvdMkv += [["\"" + str(self.dvdDest) + fid + ".ogg\"",lang3]]
			
		elif aCodec == "ogg 5.1":
			text += "mkfifo \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			text += "oggenc -r -R 44100 -q 3 -C 6 -o \"" + str(self.dvdDest) + fid + ".ogg\" \"" + str(self.dvdDest)+ "fifo-" + fid + "\"&"
			text += " mplayer " + noes + " -noframedrop -mc 0 -vc null -vo null -ao pcm:nowaveheader:file=\"" + str(self.dvdDest)+ "fifo-" + fid + "\" -srate 44100 -af volnorm=1,lavcresample=44100 -channels 6 -aid " + str(aid) + " " + org + "\n"
			text += "rm \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			self.dvdMkv += [["\"" + str(self.dvdDest) + fid + ".ogg\"",lang3]]
			
		elif aCodec == "mp3":
			text += "mkfifo \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			text += "lame --nohist -h -r -x -s 44,1 --preset fast medium \"" + str(self.dvdDest)+ "fifo-" + fid + "\" \"" + str(self.dvdDest) + fid + ".mp3\" &"
			text += " mplayer " + noes + " -mc 0 -vc null -vo null -ao pcm:nowaveheader:file=\"" + str(self.dvdDest)+ "fifo-" + fid + "\" -srate 44100 -af volnorm=1,lavcresample=44100 -channels 2 -aid " + str(aid) + " " + org + "\n"
			text += "rm \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			self.dvdMkv += [["\"" + str(self.dvdDest) + fid + ".mp3\"",lang3]]
			
		elif aCodec == "aac stereo":
			text += "mkfifo \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			text += "faac -P -q 157 -R 48000  -C 2 -X --mpeg-vers 4 -o \"" + str(self.dvdDest) + fid + ".aac\" \"" + str(self.dvdDest)+ "fifo-" + fid + "\" &"
			#text += "neroAacEnc -q 0.6 -ignorelength -if \"" + str(self.dvdDest)+ "fifo-" + fid + "\" -of \"" + str(self.dvdDest) + fid + ".aac\" &"
			text += " mplayer " + noes + " -mc 0 -vc null -vo null -ao pcm:file=\"" + str(self.dvdDest)+ "fifo-" + fid + "\" -af volnorm=1 -channels 2 -aid " + str(aid) + " " + org + "\n"
			text += "rm \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			self.dvdMkv += [["\"" + str(self.dvdDest) + fid + ".aac\"",lang3]]
			
		elif aCodec == "aac 5.1":
			text += "mkfifo \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			text += "faac -P -q 157 -R 48000 -C 6 -X --mpeg-vers 4 -o \"" + str(self.dvdDest) + fid + ".aac\" \"" + str(self.dvdDest)+ "fifo-" + fid + "\" &"
			#text += "neroAacEnc -q 0.6 -ignorelength -if \"" + str(self.dvdDest)+ "fifo-" + fid + "\" -of \"" + str(self.dvdDest) + fid + ".aac\" &"
			text += " mplayer " + noes + " -mc 0 -vc null -vo null -ao pcm:nowaveheader:file=\"" + str(self.dvdDest)+ "fifo-" + fid + "\" -af volnorm=1 -channels 6 -aid " + str(aid) + " " + org + "\n"
			text += "rm \"" + str(self.dvdDest)+ "fifo-" + fid + "\"\n"
			self.dvdMkv += [["\"" + str(self.dvdDest) + fid + ".aac\"",lang3]]
			
		return text

	def subtitulos (self,sub):
		import commands
		from re import search
		text = ""
		id 	= str(sub['id']) 
		lang 	= str(sub['idioma'])
		fid 	= "sub-t"+str(self.dvdTitle)+"-"+str(sub['id'])+"-"+str(sub['idioma'])
		lang3 	= expLang(str(sub['idioma']))
		
		noes = "-noautosub -nocache -noslices -nosound "
		if self.dvdDev == '/dev/dvd' or self.wtdRip.checkState():
			org = " -chapter " + self.dvdChapters + " \"" + str(self.dvdDest)+"dvd-t"+str(self.dvdTitle)+".vob\""
		else :
			org = " -chapter " + self.dvdChapters + " dvd://"+str(self.dvdTitle)+" -dvd-device \"" + str(self.dvdDev) + "\""
			
		text = "mencoder " + noes + " " + org + " -of rawaudio -ovc copy -o /dev/null -vobsubout \"" + str(self.dvdDest) + fid + "\" -vobsuboutindex 0 -vobsuboutid " + lang + " -sid " + id + "\n"
		cmdPaleta = "mencoder dvd://"+str(self.dvdTitle)+" -dvd-device \"" + str(self.dvdDev) + "\" -noautosub -nocache -nosound -of rawaudio -ovc copy -o /dev/null -vobsubout sub -vobsuboutindex 0 -vobsuboutid " + lang + " -sid " + id + " -frames 0 1> /dev/null 2> /dev/null"
		print cmdPaleta
		commands.getoutput(cmdPaleta)
		paleta = re.search("(palette:.*)",open ("sub.idx",'r').read()).groups()[0]
		commands.getoutput("rm sub.idx sub.sub")
		text += "echo \"" + paleta + "\" >> \"" + str(self.dvdDest) + fid + ".idx\"\n"
		self.dvdMkv += [["\"" + str(self.dvdDest) + fid + ".idx\"",lang3]] 
		return text

	def chapters (self):
		text = commands.getoutput("dvdxchap -t " + str(self.dvdTitle) + " \"" + str(self.dvdDev) + "\" > \"" + str(self.dvdDest)+"chapter-T"+str(self.dvdTitle)+".txt\"")
		return ""

	def video (self):
		from re import search
		import commands, sys
		print self.dvd.titles[self.dvdTitle]
		text = ""
		calidad = self.btnCalidad.currentText()
		tipo = self.btnTipo.currentText()
		vCodec = self.btnVideo.currentText()
		bitrate = 1000
		tamMax = 1300 * 8 * 1024 # 1300 MB en kb
		long = int(self.dvd.titles[self.dvdTitle]['duracion'])
		for i in uniq([x.row() for x in self.audioList.selectedItems()]):
			tC = self.audioList.cellWidget(i,5).currentText()
			if tC == 'ac3':
				tC_brate = int(self.dvd.titles[self.dvdTitle]['aid'][i]['bitrate'])/1000
			elif "5.1" in tC:
				tC_brate = 380
			else:
				tC_brate = 128
			bits = long * int (tC_brate)
			tamMax -= bits
			print i, tC, tC_brate, bits
		print tamMax,tamMax/long
		bitrate = tamMax/long
		if bitrate < 650: bitrate = 650
		if bitrate > 1000: bitrate = 1000
		text = ""
		cores = "1"
		try:
			cores = re.search("cpu cores.*(\d+)",commands.getoutput('cat /proc/cpuinfo')).groups()[0]
		except:
			pass
		print [cores]
		if long > 0:
			cropCmd = self.cropping("dvd://" + str(self.dvdTitle) + " -dvd-device \"" + self.dvdDev + "\"")
			
			noes = "-noautosub -nocache -noslices -nosound"
			
			if self.wtdEntrelazado.checkState(): filtros = "pullup,softskip" + cropCmd + ",pp=ci,harddup"
			else: filtros = "pullup,softskip" + cropCmd + ",harddup"
			
			if self.dvdDev == '/dev/dvd' or self.wtdRip.checkState():
				org = " -chapter " + self.dvdChapters + " \"" + str(self.dvdDest)+"dvd-t"+str(self.dvdTitle)+".vob\""
			else :
				org = " -chapter " + self.dvdChapters + " dvd://"+str(self.dvdTitle)+" -dvd-device \"" + str(self.dvdDev) + "\""
			#if self.wtdRip.checkState(): dest = self.dvdDest
			#else: dest = self.dvdDev
			
			if vCodec == 'h264' :
				if calidad == 'Optima':
				#ops = "subq=6:frameref=5:b_pyramid:weight_b:brdo:8x8dct:mixed_refs:me=umh:cabac:partitions=all:trellis=2:bframes=3:crf=21:threads="     + cores
					ops = "subq=6:frameref=5:b_pyramid:weight_b:brdo:8x8dct:mixed_refs:me=umh:cabac:partitions=all:trellis=2:bframes=3:direct_pred=auto:no_fast_pskip:threads=" + cores + ":bitrate=" + str(bitrate)
				if calidad == 'Buena':
					ops = "subq=6:frameref=3:b_pyramid:weight_b:8x8dct:mixed_refs:me=umh:cabac:trellis=1:bframes=3:direct_pred=auto:threads=" + cores + ":bitrate=" + str(bitrate)
				if calidad == 'Media':
					ops = "subq=4:frameref=1:b_pyramid:weight_b:me=hex:cabac:trellis=1:bframes=2:direct_pred=auto:threads=" + cores + ":bitrate=" + str(bitrate)
				if calidad == 'Baja':
					ops = "subq=2:frameref=1:b_pyramid:weight_b:me=dia:cabac:trellis=1:bframes=1:direct_pred=auto:threads=" + cores + ":bitrate=" + str(bitrate)
				if tipo <> "Dibujos" :
					ops += ":nodct_decimate"
				cmd = "mencoder dvd://"+str(self.dvdTitle)+" -dvd-device \"" + str(self.dvdDev) + "\" -vf " + filtros + " -oac copy -sws 7 -ovc x264 -x264encopts " + ops + " -o /dev/null -frames 25 -v "
				try:
					print cmd
					data = commands.getoutput(cmd)
					self.dvdDelay = int(1000*float(re.search("AUDIO .* (\d+\.\d+)",data).groups()[0]))
					self.dvdAspect = re.search("ODML: vprp aspect is (\d+:\d+)",data).groups()[0]
					print self.dvdDelay, self.dvdAspect, cmd
				except:
					pass
				# 2 PASADAS
				text += "mencoder " + noes + " "+org+" -vf " + filtros + " -oac copy -sws 7 -ovc x264 -x264encopts " + ops + ":turbo=1:pass=1" + " -o /dev/null\n"
				text += "mencoder " + noes + " "+org+" -vf " + filtros + " -oac copy -sws 7 -ovc x264 -x264encopts " + ops + ":pass=2" + " -o \"" + str(self.dvdDest) + "video-t"+str(self.dvdTitle)+".264\"\n"
				
				if str(self.btnContenedor.currentText()) == 'mp4':
					text += "MP4Box -aviraw video \"" + str(self.dvdDest) + "video-t"+str(self.dvdTitle)+".264\"\n"
					self.dvdMkv += [["\"" + str(self.dvdDest) + "video-t"+str(self.dvdTitle)+"_video.h264\""]] 
				if str(self.btnContenedor.currentText()) == 'mkv':
					self.dvdMkv += [["\"" + str(self.dvdDest) + "video-t"+str(self.dvdTitle)+".264\""]] 
					
			elif vCodec == 'xvid' :
				if calidad == 'Optima':
					#ops = "autoaspect:par=vga11:vhq=4:bvhq=1:chroma_opt:quant_type=mpeg:noqpel:trellis:nogmc:max_bframes=2:fixed_quant=3:threads=" + cores
					ops = "autoaspect:par=vga11:vhq=4:bvhq=1:chroma_opt:quant_type=mpeg:noqpel:trellis:nogmc:max_bframes=2:threads=" + cores + ":bitrate=" + str(bitrate)
				if calidad == 'Buena':
					ops = "autoaspect:par=vga11:vhq=2:bvhq=1:chroma_opt:quant_type=mpeg:noqpel:trellis:nogmc:max_bframes=2:threads=" + cores + ":bitrate=" + str(bitrate)
				if calidad == 'Normal':
					ops = "autoaspect:par=vga11:vhq=0:bvhq=0:nochroma_opt:quant_type=h263:noqpel:trellis:nogmc:max_bframes=2:threads=" + cores + ":bitrate=" + str(bitrate)
				if calidad == 'Baja':
					ops = "autoaspect:par=vga11:vhq=0:bvhq=0:nochroma_opt:quant_type=h263:noqpel:trellis:nogmc:max_bframes=2:threads=" + cores + ":bitrate=" + str(bitrate)
				if tipo == "Dibujos" :
					ops += ":nogreyscale:cartoon"
				elif tipo == "Blanco y Negro" :
					ops += ":nocartoon:greyscale"
				else:
					ops += ":nogreyscale:nocartoon"
				try:
					cmd = "mencoder dvd://"+str(self.dvdTitle)+" -dvd-device \"" + str(self.dvdDev) + "\" -vf " + filtros + " -oac copy -sws 7 -ovc xvid -xvidencopts " + ops + ":pass=2" + " -o /dev/null -frames 25"
					print cmd
					self.dvdDelay = int(1000*float(re.search("AUDIO .* (\d+\.\d+)",commands.getoutput(cmd)).groups()[0]))
					print self.dvdDelay, cmd
				except:
					pass
				# 2 PASADAS
				text += "mencoder " + noes + " "+org+" -vf " + filtros + " -oac copy -sws 7 -ovc xvid -xvidencopts " + ops + ":turbo:pass=1" + " -o /dev/null\n"
				text += "mencoder " + noes + " "+org+" -vf " + filtros + " -oac copy -sws 7 -ovc xvid -xvidencopts " + ops + ":pass=2" + " -o \"" + str(self.dvdDest) + "video-t"+str(self.dvdTitle)+".xvid\"\n"
				self.dvdMkv += [["\"" + str(self.dvdDest) + "video-t"+str(self.dvdTitle)+".xvid\""]] 
			return text
		else :
			return "# Titulo de longitud 0\n"

def expLang (lang):
	data = {'None':'non','unknown':'non', 'ab':'abk', 'aa':'aar', 'af':'afr', 'ak':'aka', 'sq':'alb', 'am':'amh', 'ar':'ara', 'an':'arg', 'hy':'arm', 'as':'asm', 'av':'ava', 'ae':'ave', 'ay':'aym', 'az':'aze', 'bm':'bam', 'ba':'bak', 'eu':'baq', 'be':'bel', 'bn':'ben', 'bh':'bih', 'bi':'bis', 'nb':'nob', 'bs':'bos', 'br':'bre', 'bg':'bul', 'my':'bur', 'es':'spa', 'ca':'cat', 'ch':'cha', 'ce':'che', 'ny':'nya', 'ny':'nya', 'zh':'chi', 'za':'zha', 'cu':'chu', 'cu':'chu', 'cu':'chu', 'cu':'chu', 'cu':'chu', 'cv':'chv', 'kw':'cor', 'co':'cos', 'cr':'cre', 'hr':'scr', 'cs':'cze', 'da':'dan', 'dv':'div', 'nl':'dut', 'dz':'dzo', 'en':'eng', 'eo':'epo', 'et':'est', 'ee':'ewe', 'fo':'fao', 'fj':'fij', 'fi':'fin', 'fr':'fre', 'fy':'fry', 'ff':'ful', 'gd':'gla', 'gl':'glg', 'lg':'lug', 'ka':'geo', 'de':'ger', 'ki':'kik', 'el':'gre', 'kl':'kal', 'gn':'grn', 'gu':'guj', 'ha':'hau', 'he':'heb', 'iw':'heb', 'hz':'her', 'hi':'hin', 'ho':'hmo', 'hu':'hun', 'is':'ice', 'io':'ido', 'ig':'ibo', 'id':'ind', 'ia':'ina', 'ie':'ile', 'iu':'iku', 'ik':'ipk', 'ga':'gle', 'it':'ita', 'ja':'jpn', 'jv':'jav', 'kl':'kal', 'kn':'kan', 'kr':'kau', 'ks':'kas', 'kk':'kaz', 'km':'khm', 'ki':'kik', 'rw':'kin', 'ky':'kir', 'kv':'kom', 'kg':'kon', 'ko':'kor', 'kj':'kua', 'ku':'kur', 'kj':'kua', 'lo':'lao', 'la':'lat', 'lv':'lav', 'lb':'ltz', 'li':'lim', 'li':'lim', 'li':'lim', 'ln':'lin', 'lt':'lit', 'lu':'lub', 'lb':'ltz', 'mk':'mac', 'mg':'mlg', 'ms':'may', 'ml':'mal', 'mt':'mlt', 'gv':'glv', 'mi':'mao', 'mr':'mar', 'mh':'mah', 'mo':'mol', 'mn':'mon', 'na':'nau', 'nv':'nav', 'nv':'nav', 'nd':'nde', 'nr':'nbl', 'ng':'ndo', 'ne':'nep', 'se':'sme', 'nd':'nde', 'no':'nor', 'nb':'nob', 'nn':'nno', 'ny':'nya', 'nn':'nno', 'oc':'oci', 'oj':'oji', 'cu':'chu', 'or':'ori', 'om':'orm', 'os':'oss', 'os':'oss', 'pi':'pli', 'pa':'pan', 'fa':'per', 'pl':'pol', 'pt':'por', 'oc':'oci', 'ps':'pus', 'qu':'que', 'rm':'roh', 'ro':'rum', 'rn':'run', 'ru':'rus', 'sm':'smo', 'sg':'sag', 'sa':'san', 'sc':'srd', 'gd':'gla', 'sr':'scc', 'sn':'sna', 'ii':'iii', 'sd':'snd', 'si':'sin', 'sk':'slo', 'sl':'slv', 'so':'som', 'st':'sot', 'nr':'nbl', 'es':'spa', 'su':'sun', 'sw':'swa', 'ss':'ssw', 'sv':'swe', 'tl':'tgl', 'ty':'tah', 'tg':'tgk', 'ta':'tam', 'tt':'tat', 'te':'tel', 'th':'tha', 'bo':'tib', 'ti':'tir', 'to':'ton', 'ts':'tso', 'tn':'tsn', 'tr':'tur', 'tk':'tuk', 'tw':'twi', 'ug':'uig', 'uk':'ukr', 'ur':'urd', 'uz':'uzb', 've':'ven', 'vi':'vie', 'vo':'vol', 'wa':'wln', 'cy':'wel', 'wo':'wol', 'xh':'xho', 'yi':'yid', 'yo':'yor', 'za':'zha', 'zu':'zul'}
	if data.has_key(str(lang)):
		return data[lang]
	else: 
		return lang

def seg2time(seg):
	hor = str (int(seg/60/60))
	min = str (int(seg/60)-int(hor)*60)
	seg = str (int(seg-int(seg/60)*60))	
	if len(min)  == 1:
		min = "0" + min
	if len(seg)  == 1:
		seg = "0" + seg
	return hor + ":" + min + ":" + seg

def help():
	print 'Usage: dvd2mkv [option]'
	print 'options:'
	print '-h : shows this help'
	print '-t X : where X = title number'
	print '-m X : where X = limit of MB for the film'

def checkPrograms():
	List = [['mplayer','mplayer'], ['mencoder','mencoder'], ['subtitle2vobsub','subtitleripper'], ['mkvmerge','mkvtoolnix'], ['dvdxchap','ogmtools'],['MP4Box','gpa    c'],['faac','faac'],['ffmpeg','ffmpeg']] # ['aacgain','aacgain']
	if 'command not found' not in commands.getoutput("apt-get"):
		print "## You have to install some programs, execute ", "sudo apt-get install mplayer mencoder subtitleripper mkvtoolnix ogmtools gpac faac ffmpeg"
		print "Also you have to install libdvdcss2 adding the sources following https://help.ubuntu.com/community/Medibuntu" 
	if 'command not found' not in commands.getoutput("emerge"):
		print "## You have to install some programs, execute ", "sudo emerge -u media-video/mplayer media-video/subtitleripper media-video/mkvtoolnix media-sound/ogmtools media-video/gpac media-libs/faac media-video/ffmpeg media-sound/aacgain media-libs/x264"

if __name__ == "__main__":
	# programas requeridos:
	#	transcode
	#	mplayer
	#	mencoder
	#	mkvtoolnix	-> mkvmerge
	#	subtitleripper 	-> subtitle2vobsub
	import getopt, commands
	from sys import argv
	from sys import exit
	checkPrograms()
	app = QApplication(sys.argv)
	dvd = MainWindow()
	dvd.show()
	sys.exit(app.exec_())
